﻿#define _CRT_SECURE_NO_WARNINGS  1
#pragma warning(disable:6031)
#include<stdio.h>


//int main()
//{
//	printf("%s\n", __FILE__);
//	printf("%d\n", __LINE__);
//	printf("%s\n", __DATE__);
//	printf("%s\n", __TIME__);
//	//printf("%d\n", __STDC__);
//
//	return 0;
//}


//#define MAX(X,Y) ((X)>(Y)?(X):(Y))
//
//int main()
//{
//
//	int a = 3;
//	int b = 5;
//	int m = MAX(a++, b++);
//	//相当于替换成
//	//int m = MAX(a++,b++) ((a++)>(b++)?(a++):(b++))
//	//a++和b++各会执行两次
//
//	printf("m = %d\n", m);//6
//	printf("a = %d\n", a);//4
//	printf("b = %d\n", b);//8
//
//	return 0;
//}

//#define INT_PTR int*
//int main()
//{
//	typedef int* int_ptr;
//	INT_PTR a, b;
//	int_ptr c, d;
//	return 0;
//}


//int int_max(int x, int y)
//{
//	return x > y ? x : y;
//}
//float float_max(float x, float y)
//{
//	return x > y ? x:y;
//}
//
//int main()
//{
//	
//	return 0;
//}


//#define MAX 100
//int main()
//{
//	printf("%d\n", MAX);
//#undef MAX
//	printf("%d\n", MAX);
//
//	return 0;
//}



//#include <stdio.h>
//#define __debug__
//int main()
//{
//	int i = 0;
//	int arr[10] = { 0 };
//	for (i = 0; i < 10; i++)
//	{
//		arr[i] = i;
//#ifdef __debug__
//		printf("%d\n", arr[i]);//为了观察数组是否赋值成功。
//#endif //__debug__
//	}
//	return 0;
//}


//1.
//#if 常量表达式
////...
//#endif
////常量表达式由预处理器求值。
//如：
//#define __DEBUG__ 1
//#if __DEBUG__
////..
//#endif
//2.多个分⽀的条件编译
//#if 常量表达式
////...
//#elif 常量表达式
////...
//#else
////...
//#endif
//3.判断是否被定义
//#if defined(symbol)
//#ifdef symbol
//#if !defined(symbol)
//#ifndef symbol
//4.嵌套指令
//#if defined(OS_UNIX)
//#ifdef OPTION1
//unix_version_option1();
//#endif
//#ifdef OPTION2
//unix_version_option2();
//#endif
//#elif defined(OS_MSDOS)
//#ifdef OPTION2
//msdos_version_option2();
//#endif
//#endif


//#define SWAP_BITS(num) (((num & 0x55555555)<<1)|((num & 0xAAAAAAAA)>>1))
//
//int main()
//{
//	printf("%d\n", SWAP_BITS(1));
//	printf("%d\n", SWAP_BITS(2));
//	printf("%d\n", SWAP_BITS(3));
//	printf("%d\n", SWAP_BITS(4));
//	printf("%d\n", SWAP_BITS(5));
//
//	return 0;
//}


#define OFFSETOF(type, member) ((size_t) &((type *)0)->member)
//type表示结构体类型，member表示结构体中的成员名。
//将一个空指针强制转换为指向结构体类型的指针，然后通过取成员的地址来计算偏移量。由于空指针的地址为0，所以取成员的地址就等于成员在结构体中的偏移量。

typedef struct S
{
    int a;
    char b;
    double c;
    float d;
}MyStruct;

int main()
{
    size_t s = OFFSETOF(struct S, a);
    printf("%zd\n", OFFSETOF(struct S, a));
    printf("%zd\n", OFFSETOF(struct S, b));
    printf("%zd\n", OFFSETOF(struct S, c));
    printf("%zd\n", OFFSETOF(struct S, d));
    return 0;
}